package no.progark.pong;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.view.View;
import no.progark.copter.Direction;
import no.progark.helikopter.R;

public class Ball extends View {
	
	private int posX ,posY;
	private float dX, dY;
	public double velocity;
	public double initialVelocity = 8;
	private Bitmap image;
	public int BALLSIZE; 
	//view sizes
	private int maxHeight = 0;
	private int maxWidth = 0;
	public int hitCounter= 0; //for increasing velocity.
	
	public BallDirection bd = null;

	private static Ball instance = null;
	
	protected Ball(Context context){
		super(context);
		velocity = initialVelocity;
		image = BitmapFactory.decodeResource(getResources(), R.drawable.pong_ball_test1);
		BALLSIZE = image.getHeight();
	}
	
	public static Ball getinstance(Context context){
		if(instance == null) instance = new Ball(context);
		return instance;
	}
	
	public void setMaxHeight(int h){
		maxHeight = h;
	}
	
	public void setMaxWidth(int h){
		maxWidth = h;
	}
	
	public int getMaxHeight(){
		return maxHeight;
	}
	
	public int getMaxWidth(){
		return maxWidth;
	}
	
	public int getPosX(){
		return posX;
	}
	
	public int getPosY(){
		return posY;
	}
	
	public void setPosX(int x){
		posX = x;
	}
	
	public void setPosY(int y){
		posY = y;
	}
	
	public double getVelocity(){
		return velocity;
	}
	
	public double getDx(){
		return dX;
	}
	
	public double getDy(){
		return dY;
	}
	
	public void setDx(int dX){
		this.dX = dX;
	}
	
	public void setDy(int dY){
		this.dY = dY;
	}
	
	public Bitmap getImage(){
		return image;
	}
	
	public void setRandomDirecion(Direction dir){
		System.out.println("in setRandom, dir = " + dir);
		dX = (float) ((Math.random()*4) + 1);
		dY = (float) (int) (Math.random()*4) + 1;
		dY*= (dir==Direction.UP)? -1: 1;
		if(dir == Direction.UP){
			bd = new UpBall();
			System.out.println("initialising... ball going up");
		}
		else{
			bd = new DownBall();
			System.out.println("initialising... ball going down");
		}
		normalize(); 
		
		System.out.println("SetRandomDirection");
		System.out.println("X: "+ dX);
		System.out.println("Y: "+ dY);
	}
	
	private void normalize() {
		double vel = (double) Math.sqrt(Math.pow(dX, 2)+Math.pow(dY, 2));
		dX /=vel;
		dY /=vel;
		dX *= velocity;
		dY *= velocity;
		
	}
	
	public void bounce(Direction dir){
		dX = (dir == Direction.LEFT || dir==Direction.RIGHT)?dX*(-1):dX;
	    posY = (posY < 22? 24:posY);
		dY = (dir == Direction.UP || dir==Direction.DOWN)?dY*(-1):dY;
	}
	

	public boolean collision(Canvas c, Controller c1, Controller c2){
		if(posX <= 0 || posX+ BALLSIZE >= maxWidth){
			bounce(Direction.LEFT);
			return false;
		}
		
		if(bd instanceof UpBall){
			if(bd.bounceController(c2, posX, posY, BALLSIZE)){
				System.out.println("HIT CONTROLLER!");
				hitCounter++;
				if(hitCounter % 2 == 0)velocity++;
				bounce(Direction.UP);
				bd = new DownBall();
				return false;
			}
		}
		else if(bd instanceof DownBall){
			if(bd.bounceController(c1, posX, posY, BALLSIZE)){
				System.out.println("HIT CONTROLLER!");
				hitCounter++;
				if(hitCounter % 2 == 0)velocity++;
				bounce(Direction.UP);
				bd = new UpBall();
				return false;
			}
			
		}
		
		if(posY<=0|| posY+BALLSIZE >= maxHeight){
			hitCounter=0;
			velocity = initialVelocity;
			return true;
		}
		return false;
	}

	public void initPos(Context c, Canvas canvas, int h, int w, Direction dir){
		setMaxHeight(h);
		setMaxWidth(w);		
		posX = (int) w/2;
		posY = (int) h/2;
		setRandomDirecion(dir);
	}
	
	/**
	 * 
	 * @param c
	 * @param c1
	 * @param c2
	 * @return true if ball is out of play.
	 */
	public boolean update(Canvas c, Controller c1, Controller c2){
		normalize();
		posX+=dX;
		posY+=dY;
		return collision(c, c1, c2);
	}

	public void setVelocity(double velocity) {
		this.velocity = velocity;
	}

}
